/******************************************************************************
 *                  Shanghai ChipON Micro-Electronic Co.,Ltd
 ******************************************************************************
 *  @File Name        : kf8a100fxx_eeprom.c
 *  @Author           : ChipON AE/FAE Group
 *  @Date             : 2023-12-19
 *  @HW Version       : KF8A100Fxx
 *  @Lib Version      : V2.0.1
 *  @Description      : This file provides the driver for the eeprom module
 ******************************************************************************
 *  Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
 *  All rights reserved.
 *
 *  This software is copyright protected and proprietary to
 *  Shanghai ChipON Micro-Electronic Co.,Ltd.
 *****************************************************************************/
/******************************************************************************
 *  |Date        |Version  |Author       |Description
 ******************************************************************************
 *  |2023-12-23  |V2.0     |Wang Junxiong|New creat
 *****************************************************************************/

/******************************************************************************
 **                     QAC Warnings
 *****************************************************************************/
/* PRQA S 0436 EOF #8-bit MCU Features: Direct Write Registers. */
/* PRQA S 1291, 1820, 1821, 1822, 1823, 1851, 1853, 3715, 3757, 3760 EOF #Registers are essentially unsigned numbers. */
/* PRQA S 2754 EOF #Level 7 problem due to unsupported assembly instructions. */
/* PRQA S 3768, 3771, 4130, 4393, 4434, 4443, 4446, 4461, 4532 EOF #Registers are essentially unsigned numbers. */

/******************************************************************************
 *                      Include Files
 *****************************************************************************/
#include "kf8a100fxx_eeprom.h"
/******************************************************************************
 *                      Macro Definitions
 *****************************************************************************/

/******************************************************************************
 *                      Constants
 *****************************************************************************/

/******************************************************************************
 *                      Type definitions
 *****************************************************************************/

/******************************************************************************
 *                      Variables
 *****************************************************************************/
volatile uint8_t Eeprom_Key_ONE, Eeprom_Key_TWO;

/******************************************************************************
 *                      Function definitions
 *****************************************************************************/

/**
 * @brief Data eeprom reads out a single byte of data at a specified address
 * Interrupts are turned off during reads and writes
 *
 * @param Addr eeprom addr: 00H~FFH
 * @return uint8_t eeprom data
 */
/* PRQA S 3206 1 # Used in assembly code. */
uint8_t DataEeprom_SingleDate_Read(uint8_t Addr)
{
    // clang-format off
/* PRQA S 3116 3 # Assembly syntax. */
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
	/* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277 ++ #Assembly code does not conform to C rules. */
    /* PRQA S 3110, 3112, 2000, 3202, 3109, 3139, 3417, 2015, 2214, 2753, 3426, 1842 ++ #assembly syntax. */
    /* PRQA S 2741 ++ #Control via macro definitions. */
	__asm
	;
    /* char-type parameter is in R0 */
	BANKSEL  _NVMADDRL
    /* Write address */
	MOV _NVMADDRL , R0

	/* Data read-in function */
	MOV R0 , #0x01
	MOV _NVMCTL0 , R0
	NOP
	NOP
	MOV R0,_NVMDATAL
	;
    /* char-type result return content in R0 */
	__endasm;
    /* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277, 3110, 3112, 2000, 2741, 3202, 3109, 3417, 3139-- */
        /* PRQA S 2015, 2214, 2753, 3426, 1842-- */
/* PRQA S 3116 3 # Assembly syntax. */
#pragma restore
    // clang-format on
}

/**
 * @brief Data eeprom writes single-byte data to a specified address
 * Interrupts are turned off during reads and writes
 *
 * @attention 1. Write the KEY before calling the function, and clear the KEY after the function call.
 *
 * @param Addr eeprom addr: 00H~FFH
 * @param Value eeprom data
 * @return Write eeprom status
 */
/* PRQA S 3206 1 # Used in assembly code. */
Eeprom_CmdType DataEeprom_SingleData_Write(uint8_t Addr, uint8_t Value)
{
    // clang-format off
/* PRQA S 3116 3 # Assembly syntax. */
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
	/* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277 ++ #Assembly code does not conform to C rules. */
    /* PRQA S 3110, 3112, 2000, 3202, 3109, 3139, 3417, 2015, 2214, 2753, 3426, 1842 ++ #assembly syntax. */
    /* PRQA S 2741 ++ #Control via macro definitions. */
	__asm
	BANKSEL _Eeprom_Key_ONE
	MOV R1 , _Eeprom_Key_ONE
    XOR	R1,# 0x69
    JB	PSW, 2
	JMP EEPROM_WRITE_END
	BANKSEL _Eeprom_Key_TWO
	MOV R1 , _Eeprom_Key_TWO
    XOR	R1,# 0x96
    JB	PSW, 2
	JMP EEPROM_WRITE_END
    /* Parameter address: r0 Parameter value, automatic variable STK00 */
	BANKSEL _NVMADDRL
	MOV _NVMADDRL , R0

	BANKSEL STK00
	MOV R1,STK00
	BANKSEL _NVMDATAL
	MOV _NVMDATAL,R1
    /* Recommended shutdown interruptions */
	;
    
	CWDT
	MOV R1,_INTCTL
	CLR _INTCTL,7
	JNB _INTCTL,7
	JMP $-2
	;
	CLR _EIF1,7
	;
    /* Data write execution */
    BANKSEL _Eeprom_Key_ONE
	MOV 	R6,_Eeprom_Key_ONE
    BANKSEL _Eeprom_Key_TWO
	MOV 	R5,_Eeprom_Key_TWO
	MOV 	R0,#0x04
	BANKSEL _NVMCTL0
	MOV 	_NVMCTL0,R0
    NOP
	MOV 	_NVMCTL1,R6
    NOP
	MOV 	_NVMCTL1,R5
	SET 	_NVMCTL0 , 1
	NOP
	NOP
	NOP
	NOP
	;
	MOV R2 , #0x50
	MOV R0 , #0xFF
	JNB _EIF1,7
	JMP $+7
    DECJZ R0
	JMP $-3
    DECJZ R2
	JMP $-6
	MOV R2 , #0x0C
	JMP $+2
	MOV R2 , #0x00
    /* Wait for write completion (6ms), you can consider write control, external judgment write completion under the 
     * shielding of these codes */
	CLR _EIF1,7
    /* Closed DATA EE write operation to prevent accidental writes */
	MOV R0 , #0x00
	MOV _NVMCTL0,R0
	;
	MOV R0,R2
    /* If interrupt is turned off, interrupt restored */
	;
	AND R1,#0xC0
	ORL _INTCTL,R1
	JMP $+2
EEPROM_WRITE_END:
	MOV R0 , #0xAA
	__endasm;
    /* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277, 3110, 3112, 2000, 2741, 3202, 3109, 3417, 3139-- */
        /* PRQA S 2015, 2214, 2753, 3426, 1842-- */
/* PRQA S 3116 3 # Assembly syntax. */
#pragma restore
    // clang-format on
}

/**
 * @brief Data eeprom Read multibyte data at specified address
 * If address addr+len exceeds FFH, the backward data will be written from 00H.
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param Addr eeprom addr: 00H~FFH
 * @param Data uint8_t eeprom data
 * @param Len uint8_t eeprom data length: 1~128
 */
void DataEeprom_MultiDate_Read(uint8_t Addr, uint8_t *Data, uint8_t Len)
{
    uint8_t  length   = 0u;
    uint8_t *data_ptr = Data;
    for (; length < Len; length++)
    {
        NVMADDRL = Addr + length;
        NVMCTL0  = 0x01u;
        /* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277 ++ #Assembly code does not conform to C rules. */
        /* PRQA S 3110, 3112, 2000, 3202, 3109, 3139, 3417, 2015, 2214, 2753, 3426, 1842 ++ #assembly syntax. */
        /* PRQA S 2741 ++ #Control via macro definitions. */
        __asm;
        NOP;
        NOP;
        __endasm;
        /* PRQA S 0289, 0899, 0451, 0873, 0780, 0782, 0911, 1277, 3110, 3112, 2000, 2741, 3202, 3109, 3417, 3139-- */
        /* PRQA S 2015, 2214, 2753, 3426, 1842-- */
        *data_ptr = NVMDATAL;
        data_ptr++;
    }
}

/**
 * @brief Data eeprom writes multibyte data to a specified address
 * If address addr+len exceeds FFH, the backward data will be read from 00H.
 *
 * @attention 1. This function cannot be called within an interrupt service routine.
 * 2. Write the KEY before calling the function, and clear the KEY after the function call.
 *
 * @param Addr eeprom addr: 00H~FFH
 * @param Data uint8_t eeprom data
 * @param Len uint8_t eeprom data length: 1~128
 * @return Write eeprom status
 */
Eeprom_CmdType DataEeprom_MultiData_Write(uint8_t Addr, const uint8_t *Data, uint8_t Len)
{
    uint8_t        length;
    uint8_t        addrTemp = 0u;
    uint8_t        dataTemp = 0u;
    Eeprom_CmdType retValue = EEPROM_CMD_SUCCESS;
    const uint8_t *data_ptr = Data;
    if (Eeprom_Key_ONE == 0x69 && Eeprom_Key_TWO == 0x96)
    {
        for (length = 0U; length < Len; length++)
        {
            addrTemp = Addr + length;
            dataTemp = *data_ptr;
            retValue = DataEeprom_SingleData_Write(addrTemp, dataTemp);
            if (retValue != EEPROM_CMD_SUCCESS)
            {
                break;
            }
            data_ptr++;
        }
    }
    else
    {
        retValue = EEPROM_CMD_ERROR;
    }
    return retValue;
}
/* EOF */
